package xyz.scootaloo.mono.security.aop

import cn.hutool.log.Log
import cn.hutool.log.LogFactory
import com.auth0.jwt.exceptions.SignatureVerificationException
import org.apache.shiro.authz.UnauthorizedException
import org.springframework.core.annotation.Order
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
import xyz.scootaloo.mono.base.lang.R
import xyz.scootaloo.mono.base.lang.SC
import xyz.scootaloo.mono.security.exception.NotFoundTokenException

/**
 * 全局异常处理, 将出现异常时的统一封装成[R]对象
 *
 * @author flutterdash@qq.com
 * @since 2021/8/1 10:11
 */
@Order(-1)
@RestControllerAdvice
class GlobalExceptionHandler : ResponseEntityExceptionHandler() {

    val log: Log = LogFactory.get()

    @ExceptionHandler(UnauthorizedException::class)
    fun handleUnauthorizedException(): R<Void> =
        R.fail(SC.NO_PERMISSION_FOR_THIS_PATH)

    @ExceptionHandler(NotFoundTokenException::class)
    fun handleNotFoundTokenException(): R<Void> =
        R.fail(SC.NOT_FOUND_TOKEN)

    @ExceptionHandler(SignatureVerificationException::class)
    fun handleSignatureVerificationException(): R<Void> =
        R.fail(SC.NEED_TO_LOGIN_AGAIN)

    @ExceptionHandler(Exception::class)
    fun handleServerInternalException(throwable: Throwable): R<Void> =
        R.fail(SC.SERVER_INTERNAL_ERROR).apply {
            log.debug(throwable)
        }
}
